package com.party.mobile.biz.crowdfund;

import com.alibaba.druid.support.json.JSONUtils;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.utils.BigDecimalUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.activity.Activity;
import com.party.core.model.copartner.BrokerageItem;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.counterfoil.CounterfoilBusiness;
import com.party.core.model.crowdfund.Project;
import com.party.core.model.crowdfund.SupportTransfer;
import com.party.core.model.crowdfund.SupportWithMember;
import com.party.core.model.crowdfund.TargetProject;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberGroup;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.counterfoil.ICounterfoilBusinessService;
import com.party.core.service.counterfoil.ICounterfoilService;
import com.party.core.service.crowdfund.*;
import com.party.core.service.crowdfund.biz.ProjectDetailCountBizService;
import com.party.core.service.distributor.IDistributorCountService;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.order.IOrderFormService;
import com.party.mobile.biz.analyze.MemberCopartnerDetailBizService;
import com.party.mobile.biz.analyze.MemberMerchantDetailBizService;
import com.party.mobile.biz.copartner.BrokerageBizService;
import com.party.mobile.biz.currentUser.CurrentUserBizService;
import com.party.mobile.biz.distributor.DistributorBizService;
import com.party.mobile.biz.order.MessageOrderBizService;
import com.party.mobile.biz.order.OrderBizService;
import com.party.mobile.biz.order.payOrder.CrowdfundPayOrderService;
import com.party.mobile.biz.order.payOrder.IPayOrderService;
import com.party.mobile.biz.webSocket.WebSocketBizService;
import com.party.mobile.redisPubSub.publish.RedisMsgPublish;
import com.party.mobile.web.dto.login.output.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 联合发起业务接口
 * Created by wei.li
 *
 * @date 2017/3/2 0002
 * @time 14:12
 */
@Service
public class ProjectTransferBizService {

    @Autowired
    private IProjectService projectService;

    @Autowired
    private SupportTransferBizService supportTransferBizService;

    @Autowired
    private ProjectBizService projectBizService;

    @Autowired
    private IActivityService activityService;

    @Autowired
    private ISupportTransferService supportTransferService;

    @Autowired
    private RedisMsgPublish redisMsgPublish;

    @Autowired
    private CurrentUserBizService currentUserBizService;

    @Autowired
    private WebSocketBizService webSocketBizService;

    @Autowired
    private ISupportService supportService;

    @Autowired
    private IProjectTransferService projectTransferService;
    //众筹转移已授权
    private  static  final int YET_AUTHORIZED = 1 ;
    //众筹转移成功
    private  static  final int YET_SUCCESS = 2 ;

    @Autowired
    private DistributorBizService distributorBizService;

    @Autowired
    private BrokerageBizService brokerageBizService;

    @Autowired
    private MemberMerchantDetailBizService memberMerchantDetailBizService;

    @Autowired
    private MessageOrderBizService messageOrderBizService;

    @Autowired
    private IOrderFormService orderFormService;

    @Autowired
    private OrderBizService orderBizService;

    @Autowired
    private ITargetProjectService targetProjectService;

    @Autowired
    private IDistributorCountService distributorCountService;

    @Autowired
    private MemberCopartnerDetailBizService memberCopartnerDetailBizService;

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private ProjectDetailCountBizService projectDetailCountBizService;

    @Autowired
    private ICounterfoilBusinessService counterfoilBusinessService;
    @Autowired
    private ICounterfoilService counterfoilService;
    @Autowired
    private CrowdfundPayOrderService crowdfundPayOrderService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberGroupService memberGroupService;

    /**
     * @param activity           活动
     * @param source             原众筹
     * @param counterfoilId      票据id
     * @param project            目标众筹
     * @param transferThreadPool 支持转移线程池
     * @param targetId           目标项目id
     * @return 目标项目的众筹id
     * @author yifeng
     * @Description 支持者转移 （带事务提交）
     * @date 14:28 2019/6/27
     **/
    private String doTransferSupport(Activity activity, Project source, String counterfoilId, Project project,
                                    ExecutorService transferThreadPool, String targetId) {
        String targetProId = "";
        if (null == project) {
            // 自动报名
            targetProId = projectBizService.apply(activity, source, counterfoilId);
        } else {
            targetProId = project.getId();
        }

        //设置最后支持时间LastSupportDate
        Project project1 = projectService.get(targetProId);
        if (project1 != null) {
            List<SupportWithMember> byProjectId = supportService.findByProjectId(source.getId());
            SupportWithMember supportWithMember = byProjectId.get(0);
            if (supportWithMember != null) {
                //最后支持时间
                project1.setLastSupportDate(supportWithMember.getCreateDate());
            }
            projectService.update(project1);
        }
        SupportTransfer supportTransfer = supportTransferService.getBySourceId(source.getId());

        //记录转移的支持者
        try {
            projectTransferService.recordTransferSupporters(source.getId(), supportTransfer.getId());
        } catch (Exception e) {
            logger.error("记录转移的支持者异常", e);
        }

        supportTransferBizService.transfer(source.getId(), targetProId, transferThreadPool);


        //众筹转移活动报名表状态维护
        try {
            projectTransferService.projectMemberActStateUpdate(targetProId, targetId, counterfoilId);
        } catch (Exception e) {
            logger.error("众筹转移活动报名表状态维护异常", e);
        }
        return targetProId;
    }

    /**
     * @param isGt
     * @param sourceId           原众筹id
     * @param targetProId        目标众筹id
     * @param transferThreadPool 支持者转移线程池
     * @return 提示给用户的信息
     * @author yifeng
     * @Description 转移成功后的数据校正（不带事务）
     * @date 14:34 2019/6/27
     **/
    private Map<String, String> doReviseData(boolean isGt, String sourceId, String targetProId, ExecutorService transferThreadPool) {
        while (true) {
            if (transferThreadPool.isTerminated()) {
                supportTransferBizService.reviseFavorer(sourceId, targetProId);
                try {
                    // 校验统计分析
                    projectDetailCountBizService.reviseProjectWhenTransfer(sourceId, targetProId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
            }
        }

        String message = "";
        String result = "";
        List<SupportWithMember> tranAfterList = supportService.findByProjectId(sourceId);
        if (tranAfterList.size() == 0) {
            //转移已授权
            SupportTransfer supportTransfer = supportTransferService.getBySourceId(sourceId);
            supportTransfer.setIsAuthorized(YET_AUTHORIZED);
            supportTransfer.setTargetProId(targetProId);
            supportTransferService.update(supportTransfer);
            //众筹项目转移成功
            Project project = projectService.get(sourceId);
            project.setTransferStatus(YET_SUCCESS);
            projectService.update(project);

            logger.info("mobile确认转移-------当前转移状态:" + project.getTransferStatus());

            // 众筹成功后的业务处理
            new Thread(() -> dealPayBusiness(targetProId)).start();

            message = "转移已全部完成";
            result = "success";
        } else {
            if (isGt) {
                message = "抱歉有" + "转移后的金额大于目标金额,不能转移";
            } else {
                message = "抱歉有" + tranAfterList.size() + "个支持者暂未转移成功, 可刷新页面 ，点击确定按钮继续转移";
            }
        }
        Map<String, String> json = Maps.newHashMap();
        json.put("result", result + "");
        json.put("message", message);
        return json;
    }

    /**
     * 转换支持
     *
     * @param sourceId    资源编号
     * @param targetId    目标编号
     * @param currentUser
     */
    public void transferSupport(String sourceId, String targetId, CurrentUser currentUser) {
        Activity activity = activityService.get(targetId);
        Project source = projectService.get(sourceId);

        String counterfoilId = null;

        List<Counterfoil> counterfoils = counterfoilService.list(new Counterfoil(activity.getEventId(),
                Constant.BUSINESS_TYPE_CROWDFUND));
        if (counterfoils.size() > 1) {
            // 多个票据，且没有报名。则不能转移，因为不知道自动报名时，报名哪个票据
            Project myProject = projectService.getMyProject(targetId, source.getAuthorId());
            if (null == myProject) {
                throw new BusinessException("目标项目存在多个票据,不能转移");
            }
            CounterfoilBusiness counterfoilBusiness = counterfoilBusinessService.findByBusinessId(myProject.getId());
            if (null != counterfoilBusiness) {
                Counterfoil counterfoil = counterfoilService.get(counterfoilBusiness.getCounterfoilId());
                if (source.getActualAmount() > counterfoil.getPayment()) {
                    throw new BusinessException("转移后的金额大于目标金额,不能转移");
                }
                counterfoilId = counterfoil.getId();
            }
        } else if (counterfoils.size() == 1) {
            if (source.getActualAmount() > counterfoils.get(0).getPayment()) {
                throw new BusinessException("转移后的金额大于目标金额,不能转移");
            }
            counterfoilId = counterfoils.get(0).getId();
        } else if (counterfoils.size() == 0) {
            throw new BusinessException("该项目不存在票据,不能转移");
        }

        //根据目标和发起人查询
        Project target = projectService.findByTargetWithAuthor(targetId, source.getAuthorId());

        //已经报名
        boolean isGt = false;
        if (null != target) {
            if (Constant.IS_CROWFUND_ING.equals(target.getIsSuccess())) {
                //验证众筹金额
                float realAmount = BigDecimalUtils.add(target.getActualAmount(), source.getActualAmount());
                realAmount = BigDecimalUtils.round(realAmount, 2);
                if (realAmount > target.getTargetAmount()) {
                    isGt = true;
                }
            } else {
                isGt = true;
            }
        }

        ExecutorService transferThreadPool = Executors.newFixedThreadPool(100);

        String targetProId = this.doTransferSupport(activity, source, counterfoilId, target, transferThreadPool, targetId);

        boolean finalIsGt = isGt;
        new Thread(new Runnable() {
            @Override
            public void run() {
                Map<String, String> json = doReviseData(finalIsGt, sourceId, targetProId, transferThreadPool);
                Map<String, String> newJson = Maps.newHashMap();
                json.put("memberId", currentUser.getId());
                newJson.putAll(json);
                String param = JSONUtils.toJSONString(newJson);
                redisMsgPublish.publish("projectTansferMobile", param);
            }
        }).start();
    }

    /**
     * 众筹成功后的业务处理
     *
     * @param targetProId 众筹id
     */
    public void dealPayBusiness(String targetProId) {
        try {
            // 目标众筹
            Project project = projectService.get(targetProId);
            TargetProject tp = targetProjectService.findByProjectId(project.getId());
            Activity activity = activityService.get(tp.getTargetId());

            if (Constant.IS_SUCCESS.equals(project.getIsSuccess())) {
                project.setUseTime(Long.valueOf(60000));
                projectService.update(project);
                DistributorRelation distributorRelation = distributorBizService.getDistributorRelation(targetProId);
                if (null != distributorRelation && DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributorRelation.getType())) {
                    try {
                        brokerageBizService.insertBrokerageItem(targetProId, tp.getTargetId(), BrokerageItem.TYPE_CROWDFUND, project.getAuthorId());
                    } catch (Exception e) {
                        logger.error("众筹支持者转移后，众筹成功的，佣金异常", e);
                    }
                }

                //更新成功数
                try {
                    memberCopartnerDetailBizService.updateSuccess(project.getId());
                } catch (Exception e) {
                    logger.error("更新合伙人成功数异常", e);
                }

                //更新联合发起统计
                try {
                    distributorCountService.countSuccessNum(project.getId());
                } catch (Exception e) {
                    logger.error("更新联合发起统计异常", e);
                }

                Member crowdfundMember = memberService.get(project.getAuthorId());
                MemberGroup orgMember = memberGroupService.get(activity.getMember());

                // 如果众筹成功了, 修改机构成功数
                try {
                    memberMerchantDetailBizService.updateSuccessNum(activity.getMemberId());
                } catch (Exception e) {
                    logger.error("众筹成功后更新机构成功数异常", e);
                }
                // 消息推送
                long start13 = System.currentTimeMillis();
                crowdfundPayOrderService.sendCrowdfundSuccessMessage(crowdfundMember, orgMember, project.getId(),
                        activity, tp.getOrderId());
                long end13 = System.currentTimeMillis();
                logger.info("消息推送：{}(ms)",(end13 - start13));
                // 海报推送
                new Thread(() -> {
                    try {
                        long start12 = System.currentTimeMillis();
                        crowdfundPayOrderService.sendCrowdfundSuccessPoster(project, activity.getMember(),
                                crowdfundMember, orgMember, activity);
                        long end12 = System.currentTimeMillis();
                        logger.info("画海报推送用时：{}(ms)",(end12 - start12));
                    } catch (Exception e) {
                        logger.error("画海报推送用时异常", e);
                    }
                }).start();



                /*final String projectId = project.getId();
                final String orderMemberId = project.getAuthorId();
                if (project.getPayType() == 0) {
                    //在微信公众号上给众筹者推送成功海报
                    final String activityMemberId = activity.getMember();
                    new Thread(() -> {
                        try {
                            messageOrderBizService.raiseSuccessfulPostersSend(projectId, orderMemberId, activityMemberId);
                        } catch (Exception e) {
                            logger.error("推送成功海报失败", e);
                        }
                    }).start();
                }

                //如果众筹成功了, 就发码
                try {
                    OrderForm mainOrder = orderFormService.get(tp.getOrderId());
                    orderBizService.sendCode(mainOrder);
                } catch (Exception e) {
                    logger.error("众筹成功后发码异常", e);
                }*/
            }
        } catch (Exception e) {
            logger.error("转移成功后，众筹成功，处理成功后的业务异常", e);
        }
    }
}
